{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Celeribity Recognition using Amazon Rekognition"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "This notebook provides a walkthrough of [celebrity recognition API](https://docs.aws.amazon.com/rekognition/latest/dg/celebrities.html) in Amazon Rekognition. You can quickly identify well known people in your video and image libraries to catalog footage and photos for marketing, advertising, and media industry use cases."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Initialize stuff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialise Notebook\n",
    "import boto3\n",
    "from IPython.display import HTML, display, Image as IImage\n",
    "from PIL import Image, ImageDraw, ImageFont\n",
    "import time\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sagemaker\n",
    "\n",
    "sagemaker_session = sagemaker.Session()\n",
    "role = sagemaker.get_execution_role()\n",
    "bucket = sagemaker_session.default_bucket()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Curent AWS Region. Use this to choose corresponding S3 bucket with sample content\n",
    "\n",
    "mySession = boto3.session.Session()\n",
    "awsRegion = mySession.region_name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Init clients\n",
    "rekognition = boto3.client(\"rekognition\")\n",
    "s3 = boto3.client(\"s3\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# S3 bucket that contains sample images and videos\n",
    "\n",
    "# We are providing sample images and videos in this bucket so\n",
    "# you do not have to manually download/upload test images and videos.\n",
    "\n",
    "bucketName = bucket"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create temporary directory\n",
    "# This directory is not needed to call Rekognition APIs.\n",
    "# We will only use this directory to download images from S3 bucket and draw bounding boxes\n",
    "# around recognized celebrities to show them here in the notebook.\n",
    "\n",
    "!mkdir -p m1tmp\n",
    "tempFolder = \"m1tmp/\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Recognize celebrities in image\n",
    "***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "imageName = \"content-moderation/media/GrandTourjc.png\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<img src=\"https://sagemaker-us-east-1-835319576252.s3.amazonaws.com/content-moderation/media/GrandTourjc.png?AWSAccessKeyId=ASIA4E7HNG26F52QMHYN&Signature=k%2FJgFqt4SCE9Cvtrp2qPXmGZmrs%3D&x-amz-security-token=IQoJb3JpZ2luX2VjENT%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJIMEYCIQCsYvJDvo272zzcgIFX5kU0wmDYK2ZgPNX5jpS4HVR6PwIhAOWTBoWaOv8KOieOj%2F5f4Zf%2FkBE8nbvM7ccV9w1x4VAFKvUCCD0QARoMODM1MzE5NTc2MjUyIgwL%2Be5VOWIUoYRflVoq0gJ5Ktr7klOhoFQ9txuS9Ivl8NaZCUBEB4UnTsY6PpXlWeO90D1%2BTC9HbZI1W4uQ98z%2FaLPn4nYaAdeVFqBHC9WzMd0QA%2Bbimk3II5sPya0IycLVfuhLJjSs%2BGPfERhdu0TwQTBUxM2d9whcpvyx1XYgdvs8SJEwu4Z0b9lflD3Uw9RI%2BNRHS0rZyzoOHubQDZ1bPNWqgMBZaEEquRr1jF5btsYxXtT%2FmZ1My21STfVYzOLQZfhIU1xnEInsCntANqJpC2qu0qwRaWuApxWJFEFFLQRvORAWzbfk0%2B0yp3wDTa%2BLOBVV9PM32d%2B9ZoEy%2B3GocJ6lzO1VxL1IgZ4Qay7Km8AduNNDjXhWWOM%2Bi8zXg7GTXF5o1HiQWb6hpgbwvReLgWy62mY9ihTKCnCsRdRdM0nu7ZHzGT5UEnOKiNFDwfR4mzr2qqpdkp%2Bbtix%2FuP0XAzCD1Z39BTrCAbZQqLlxflAYvPOu4eZ95H3UfcUJWDqoD2WR994ip1ytRyWVN3SHrWtSsdRtYkW6d9mu5eyLFaY275%2BEflKb%2BchgiE0qvocCzCTtw%2BySxCykOEXh6eJXmZj%2BTYmFkym7hxd6QWwDWO9mlef1zFc%2FqA4AUJQKXiofdJB%2Borw6W96%2F7%2FZOTKb%2B96rttD7DSXBb5tAs25Hf15iTCWTipqXaoEGsoV4k67ZYbuNmIGuwCL31NLFjz16tqSXMVVY3JdI7Qch7&Expires=1604812264\"/>"
      ],
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(IImage(url=s3.generate_presigned_url(\"get_object\", Params={\"Bucket\": bucketName, \"Key\": imageName})))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Call Rekognition to recognize celebrities in the image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "ename": "InvalidS3ObjectException",
     "evalue": "An error occurred (InvalidS3ObjectException) when calling the RecognizeCelebrities operation: Unable to get object metadata from S3. Check object key, region and/or access permissions.",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mInvalidS3ObjectException\u001b[0m                  Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-9-e0ea19555e8d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      6\u001b[0m         'S3Object': {\n\u001b[1;32m      7\u001b[0m             \u001b[0;34m'Bucket'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mbucketName\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m             \u001b[0;34m'Name'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mimageName\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      9\u001b[0m         }\n\u001b[1;32m     10\u001b[0m     }\n",
      "\u001b[0;32m~/anaconda3/envs/python3/lib/python3.6/site-packages/botocore/client.py\u001b[0m in \u001b[0;36m_api_call\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m    335\u001b[0m                     \"%s() only accepts keyword arguments.\" % py_operation_name)\n\u001b[1;32m    336\u001b[0m             \u001b[0;31m# The \"self\" in this scope is referring to the BaseClient.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 337\u001b[0;31m             \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_make_api_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moperation_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    338\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    339\u001b[0m         \u001b[0m_api_call\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name__\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpy_operation_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/envs/python3/lib/python3.6/site-packages/botocore/client.py\u001b[0m in \u001b[0;36m_make_api_call\u001b[0;34m(self, operation_name, api_params)\u001b[0m\n\u001b[1;32m    654\u001b[0m             \u001b[0merror_code\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mparsed_response\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Error\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Code\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    655\u001b[0m             \u001b[0merror_class\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merror_code\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 656\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0merror_class\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparsed_response\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moperation_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    657\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    658\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mparsed_response\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mInvalidS3ObjectException\u001b[0m: An error occurred (InvalidS3ObjectException) when calling the RecognizeCelebrities operation: Unable to get object metadata from S3. Check object key, region and/or access permissions."
     ]
    }
   ],
   "source": [
    "# Call Amazon Rekognition to recognize celebrities in the image\n",
    "# https://docs.aws.amazon.com/rekognition/latest/dg/API_RecognizeCelebrities.html\n",
    "\n",
    "recognizeCelebritiesResponse = rekognition.recognize_celebrities(\n",
    "    Image={\n",
    "        \"S3Object\": {\n",
    "            \"Bucket\": bucketName,\n",
    "            \"Name\": imageName,\n",
    "        }\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Review the raw JSON reponse from Rekognition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Show JSON response returned by Rekognition Celebrity Recognition API\n",
    "# In the JSON response below, you will see CelebrityFaces which contains information about recognized celebrities.\n",
    "# For each recognized celebrity, you will see information like Name, Id, Urls and additional information about\n",
    "# their facial attributes.\n",
    "\n",
    "display(recognizeCelebritiesResponse)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Show image with bounding boxes around recognized celebrities"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define a function that will display image with bounded boxes around recognized celebrites\n",
    "# We will call this function in next step\n",
    "\n",
    "\n",
    "def drawBoundingBoxes(sourceImage, boxes):\n",
    "    # blue, green, red, grey\n",
    "    colors = ((255, 255, 255), (255, 255, 255), (76, 182, 252), (52, 194, 123))\n",
    "\n",
    "    # Download image locally\n",
    "    imageLocation = tempFolder + os.path.basename(sourceImage)\n",
    "    s3.download_file(bucketName, sourceImage, imageLocation)\n",
    "\n",
    "    # Draws BB on Image\n",
    "    bbImage = Image.open(imageLocation)\n",
    "    draw = ImageDraw.Draw(bbImage)\n",
    "    width, height = bbImage.size\n",
    "    col = 0\n",
    "    maxcol = len(colors)\n",
    "    line = 3\n",
    "    for box in boxes:\n",
    "        x1 = int(box[1][\"Left\"] * width)\n",
    "        y1 = int(box[1][\"Top\"] * height)\n",
    "        x2 = int(box[1][\"Left\"] * width + box[1][\"Width\"] * width)\n",
    "        y2 = int(box[1][\"Top\"] * height + box[1][\"Height\"] * height)\n",
    "\n",
    "        draw.text((x1, y1), box[0], colors[col])\n",
    "        for l in range(line):\n",
    "            draw.rectangle((x1 - l, y1 - l, x2 + l, y2 + l), outline=colors[col])\n",
    "        col = (col + 1) % maxcol\n",
    "\n",
    "    imageFormat = \"PNG\"\n",
    "    ext = sourceImage.lower()\n",
    "    if ext.endswith(\"jpg\") or ext.endswith(\"jpeg\"):\n",
    "        imageFormat = \"JPEG\"\n",
    "\n",
    "    bbImage.save(imageLocation, format=imageFormat)\n",
    "\n",
    "    display(bbImage)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'recognizeCelebritiesResponse' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-11-a6e18edac4a9>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0mboxes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mcelebrities\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrecognizeCelebritiesResponse\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'CelebrityFaces'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      5\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mcelebrity\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcelebrities\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m     \u001b[0mboxes\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcelebrity\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Name'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcelebrity\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Face'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'BoundingBox'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'recognizeCelebritiesResponse' is not defined"
     ]
    }
   ],
   "source": [
    "# Extract bounding box information from JSON response above and display image with bounding boxes around celebrites.\n",
    "\n",
    "boxes = []\n",
    "celebrities = recognizeCelebritiesResponse[\"CelebrityFaces\"]\n",
    "for celebrity in celebrities:\n",
    "    boxes.append((celebrity[\"Name\"], celebrity[\"Face\"][\"BoundingBox\"]))\n",
    "\n",
    "drawBoundingBoxes(imageName, boxes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Recognize celebrities in video\n",
    " Celebrity recognition in video is an async operation. \n",
    " https://docs.aws.amazon.com/rekognition/latest/dg/API_StartCelebrityRecognition.html\n",
    " - We first start celebrity recognition job which returns a Job Id.\n",
    " - We can then call `get_celebrity_recognition` to get the job status and after job is complete, we can get celebrity metadata.\n",
    " - In production use cases, you would usually use StepFucntion or SNS topic to get notified when job is complete.\n",
    "***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "videoName = \"content-moderation/media/GrandTour720.mp4\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Call Rekognition to start a job for celebrity rekognition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Start celebrity recognition job\n",
    "startCelebrityRekognition = rekognition.start_celebrity_recognition(\n",
    "    Video={\n",
    "        \"S3Object\": {\n",
    "            \"Bucket\": bucketName,\n",
    "            \"Name\": videoName,\n",
    "        }\n",
    "    },\n",
    ")\n",
    "\n",
    "celebrityJobId = startCelebrityRekognition[\"JobId\"]\n",
    "display(\"Job Id: {0}\".format(celebrityJobId))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Wait for celebrity rekognition job to complete"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "\n",
    "# Wait for celebrity recognition job to complete\n",
    "# In production use cases, you would usually use StepFucntion or SNS topic to get notified when job is complete.\n",
    "getCelebrityRecognition = rekognition.get_celebrity_recognition(JobId=celebrityJobId, SortBy=\"TIMESTAMP\")\n",
    "\n",
    "while getCelebrityRecognition[\"JobStatus\"] == \"IN_PROGRESS\":\n",
    "    time.sleep(5)\n",
    "    print(\".\", end=\"\")\n",
    "\n",
    "    getCelebrityRecognition = rekognition.get_celebrity_recognition(JobId=celebrityJobId, SortBy=\"TIMESTAMP\")\n",
    "\n",
    "display(getCelebrityRecognition[\"JobStatus\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Review raw JSON reponse from Rekognition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Show JSON response returned by Rekognition Celebrity Recognition API\n",
    "# In the JSON response below, you will see list Celebrities which contains information about recognized celebrities.\n",
    "# For each recognized celebrity, you will see information like Timestamp, Name, Id, Urls\n",
    "# and additional information about their facial attributes.\n",
    "\n",
    "display(getCelebrityRecognition)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Dislpay names of recognized celebrities in the video"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "theCelebs = {}\n",
    "\n",
    "# Display timestamps and celebrites detected at that time\n",
    "strDetail = \"Celebrites detected in video<br>=======================================<br>\"\n",
    "strOverall = \"Celebrities in the overall video:<br>=======================================<br>\"\n",
    "\n",
    "# Celebrities detected in each frame\n",
    "for celebrity in getCelebrityRecognition[\"Celebrities\"]:\n",
    "    if \"Celebrity\" in celebrity:\n",
    "        cconfidence = celebrity[\"Celebrity\"][\"Confidence\"]\n",
    "        if cconfidence > 95:\n",
    "            ts = celebrity[\"Timestamp\"]\n",
    "            cname = celebrity[\"Celebrity\"][\"Name\"]\n",
    "            strDetail = strDetail + \"At {} ms: {} (Confidence: {})<br>\".format(ts, cname, round(cconfidence, 2))\n",
    "            if not cname in theCelebs:\n",
    "                theCelebs[cname] = cname\n",
    "\n",
    "\n",
    "# Unique faces detected in video\n",
    "for theCeleb in theCelebs:\n",
    "    strOverall = strOverall + \"Name: {}<br>\".format(theCeleb)\n",
    "\n",
    "# Display results\n",
    "display(HTML(strOverall))\n",
    "# display(HTML(strDetail))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Show video in the player"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Show video in a player\n",
    "\n",
    "s3FilePrefix = \"https://s3.amazonaws.com\"\n",
    "if not awsRegion == \"us-east-1\":\n",
    "    s3FilePrefix = \"https://s3-{}.amazonaws.com\".format(awsRegion)\n",
    "\n",
    "s3VideoUrl = \"{0}/{1}/{2}\".format(s3FilePrefix, bucketName, videoName)\n",
    "\n",
    "videoTag = \"<video controls='controls' autoplay width='640' height='360' name='Video' src='{0}'></video>\".format(\n",
    "    s3VideoUrl\n",
    ")\n",
    "\n",
    "videoui = \"<table><tr><td style='vertical-align: top'>{}</td><td>{}</td></tr></table>\".format(videoTag, strDetail)\n",
    "\n",
    "display(HTML(videoui))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Try recognizing custom celebrities \n",
    "***"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Now let us try an image with non-celebrities in the image.\n",
    "\n",
    "customCelebrityImageName = \"content-moderation/media/serverless-bytes.png\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "display(\n",
    "    IImage(url=s3.generate_presigned_url(\"get_object\", Params={\"Bucket\": bucketName, \"Key\": customCelebrityImageName}))\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Call Amazon Rekognition to recognize celebrities in the image\n",
    "\n",
    "customCelebrityResponse = rekognition.recognize_celebrities(\n",
    "    Image={\n",
    "        \"S3Object\": {\n",
    "            \"Bucket\": bucketName,\n",
    "            \"Name\": customCelebrityImageName,\n",
    "        }\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Display Rekognition response\n",
    "# You will see Rekognition return an empty list for CelebrityFaces and\n",
    "# UnrecognizedFaces list with unrecognized faces that were detected in the image.\n",
    "# In the next module you will learn how to get custom-celebrity faces recognized.\n",
    "\n",
    "display(customCelebrityResponse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Show image and bounded boxes around detected faces\n",
    "\n",
    "# Extract BB info from response\n",
    "cboxes = []\n",
    "faces = customCelebrityResponse[\"UnrecognizedFaces\"]\n",
    "for face in faces:\n",
    "    cboxes.append((\"Unrecognized Face\", face[\"BoundingBox\"]))\n",
    "\n",
    "drawBoundingBoxes(customCelebrityImageName, cboxes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***\n",
    "### References\n",
    "- https://docs.aws.amazon.com/rekognition/latest/dg/celebrities.html\n",
    "- https://docs.aws.amazon.com/rekognition/latest/dg/API_RecognizeCelebrities.html\n",
    "- https://docs.aws.amazon.com/rekognition/latest/dg/API_StartCelebrityRecognition.html\n",
    "- https://docs.aws.amazon.com/rekognition/latest/dg/API_GetCelebrityRecognition.html\n",
    "\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You have successfully used Amazon Rekognition to identify celebrities in images an videos. In the next module, Recognize Custom Celebrities, you will learn how to recognize your custom celebrities in the images and videos."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "conda_python3",
   "language": "python",
   "name": "conda_python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
